import { Body, Controller, Get, Inject, Post, Query, Req, Res, UnauthorizedException, UseGuards, } from "@nestjs/common";
import { AuthService } from "./auth.service";
import { AuthGuard } from "src/guards/auth.guard";
import { Public } from "src/decorators/is-public.decorator";
import { RolesGuard } from "src/guards/roles.guard";
import { CheckRoles } from "src/decorators/check-roles.decorator";
import type { AuthorInfo } from "src/providers/author";
import type { AsyncConfig } from "src/providers/async.config";
import { ASYNC_CONFIG_KEY, AUTHOR_INFO_KEY } from "src/constant/provider.const";
import { ApiDescription } from "src/decorators/api-description.decorator";
import { LoginDto } from "src/dtos/uses/login.dto";
import type { Response, Request } from "express";

@Controller('auth')
export class AuthController {
    constructor(
        private readonly authService: AuthService,
        @Inject(AUTHOR_INFO_KEY) private readonly authorInfo: AuthorInfo,
        @Inject(ASYNC_CONFIG_KEY) private readonly asyncConfig: AsyncConfig) { }


    @Public()
    @ApiDescription('Sign in with username and password')
    @Post('/sign-in')
    async signIn(@Body() body: LoginDto, @Res() res: Response, @Req() req: Request) {
        const { accessToken, user } = await this.authService.signIn(body.username, body.password);
        if (!accessToken) {
            throw new UnauthorizedException("用户名或密码错误");
        }
        res.cookie('accessToken', accessToken, {
            httpOnly: true,
            maxAge: 60 * 1000 * 60,
            secure: true,
            sameSite: 'lax',
        });

        req.session.visits = 0;
        req.session.username = user.username;
        req.session.userId = user.id;

        return res.send({
            success: true,
            message: 'Login Successfully',
            accessToken,
        });
    }

    @ApiDescription('Find all users')
    // 具体的某个API使用AuthGuard
    @UseGuards(AuthGuard, RolesGuard)
    @CheckRoles('admin') // @SetMetadata('roles', ['admin'])
    @Get('/users')
    async findUsers() {
        return await this.authService.findUsers();
    }

    @ApiDescription('Get custom provider info')
    @Public()
    @Get('/custom-provider')
    async getCustomProviderInfo() {
        return this.authorInfo;
    }


    @ApiDescription('Get async config')
    @Public()
    @Get('/async-config')
    async getAsyncConfig() {
        return this.asyncConfig;
    }

    @ApiDescription('Get session info')
    @Public()
    @Get('/me')
    async getSession(@Req() req: Request) {
        if(!req.session.username) {
            throw new UnauthorizedException("Not logged in");
        }
        console.info('======= Print current session =======',req.session)
        req.session.visits += 1;
        return {
            username: req.session.username,
            userId: req.session.userId,
            visits: req.session.visits,
        }
    }

    @ApiDescription('Sign out')
    @Public()
    @Post('/sign-out')
    async signOut(@Res() res: Response, @Req() req: Request) {
        req.session.destroy((err) => {
            if (err) {
                throw new UnauthorizedException("Sign out failed");
            }
        });
        res.clearCookie('accessToken');
        return res.send({
            success: true,
            message: 'Sign out Successfully',
        });
    }

}
